import { useRequest } from "@/hooks/use-request";
import useSyncState from "@/hooks/use-sync-state";
import { antdUtils } from "@/utils/antd";
import { t } from "@/utils/i18n";
import { useInViewport } from "ahooks";
import { Button, Col, DatePicker, Form, Modal, Row, Select, Table } from "antd";
import { ColumnsType, TablePaginationConfig } from "antd/es/table";
import dayjs from "dayjs";
import { useEffect, useRef, useState } from "react";
import { useLocation } from "react-router-dom";
import { useImmer } from "use-immer";
import projectService from "../service";

import { Packer } from "docx";
import { saveAs } from "file-saver";
import { DocumentCreator } from "./cv-generator";

const ProjectPlan = () => {
  const ref = useRef(null);
  const [inViewport] = useInViewport(ref);
  const [exportVisible, setExportVisible] = useState(false);
  const [form] = Form.useForm();
  const location = useLocation();
  const [list, setList] = useState<any[]>([]);
  const [ulist, setUList] = useImmer<any[]>([]);
  const [pData, setPData] = useSyncState({
    id: String || null,
    name: String || null,
  });
  const [allUsers, setAllUsers] = useImmer<any[]>([]);
  const [pagination, setPagination] = useImmer<TablePaginationConfig>({
    current: 1,
    pageSize: 8,
  });
  const { runAsync: findPrijectPlan } = useRequest(
    projectService.findPrijectPlan,
    {
      manual: true,
    }
  );
  const { runAsync: getAllUser } = useRequest(projectService.getAllUser, {
    manual: true,
  });

  useEffect(() => {
    if (inViewport && location.state?.id && location.state?.name) {
      setPData(
        { id: location.state?.id, name: location.state?.name },
        (data: any) => {
          getData(data.id);
        }
      );
    }
  }, [location.state, inViewport]);

  const getData = async (id: string) => {
    setPagination((old) => {
      old.current = 1;
      old.pageSize = 8;
    });
    const { current, pageSize } = pagination || {};
    const [error, data] = await findPrijectPlan({
      page: (current ? current : 1) - 1,
      size: pageSize,
      id: id,
    });

    if (error) {
      antdUtils.message?.error(error);
      return;
    }
    const uList: any[] = [];
    if (allUsers.length <= 0) {
      const [errorU, dataU] = await getAllUser();
      if (!errorU) {
        const list = dataU.map((user: any) => {
          return {
            value: user.id,
            label: user.nickName,
          };
        });
        setAllUsers(list);
        uList.push(...list);
      }
    } else {
      uList.push(...allUsers);
    }
    setUList((old) => {
      old.length = 0;
      old.push(...uList);
    });
    setList(
      (data as any).data.map((item: any) => {
        item.notes = item.notes ? JSON.parse(item.notes) : [];
        const index = uList.findIndex((e) => e.value === item.userid);
        if (index != -1) {
          item.userNickname = uList[index].label;
        }
        return item;
      })
    );
    setPagination((old) => {
      old.total = (data as any).total;
    });
  };

  const tabChangeHandle = (tablePagination: TablePaginationConfig) => {
    setPagination(tablePagination);
    form.submit();
  };

  const onSearch = async (value: any) => {
    let startTime, endTime;
    if (value.time) {
      startTime = dayjs(value.time[0]).format("YYYY-MM-DD");
      endTime = dayjs(value.time[1]).format("YYYY-MM-DD");
    }
    const { pageSize, current } = pagination || {};
    const [error, data] = await findPrijectPlan({
      page: (current ? current : 1) - 1,
      size: pageSize,
      id: pData.id,
      startTime: startTime,
      endTime: endTime,
      userid: value.userid,
      state: value.state,
    });
    if (error) {
      antdUtils.message?.error(error);
      return;
    }
    setList(
      (data as any).data.map((item: any) => {
        item.notes = item.notes ? JSON.parse(item.notes) : [];
        const index = allUsers.findIndex((e) => e.value === item.userid);
        if (index != -1) {
          item.userNickname = allUsers[index].label;
        }
        return item;
      })
    );
    setPagination((old) => {
      old.total = (data as any).total;
    });
  };

  const columns = (): ColumnsType<any> => [
    {
      title: "计划名",
      dataIndex: "name",
      key: "name",
      width: 200,
      fixed: "left",
    },
    {
      title: "负责人",
      dataIndex: "userNickname",
      key: "userNickname",
      width: 100,
      fixed: "left",
    },
    {
      title: "状态",
      dataIndex: "state",
      key: "state",
      width: 100,
      fixed: "left",
      render: (_, item: any) => <>{getPlanState(item.state)}</>,
    },
    {
      title: "计划开始时间",
      dataIndex: "startTime",
      key: "startTime",
      width: 130,
      defaultSortOrder: "descend",
    },
    {
      title: "预计完成时间",
      dataIndex: "planOverTime",
      key: "planOverTime",
      width: 150,
    },
    {
      title: "第一次执行时间",
      dataIndex: "executeTimeFirst",
      key: "executeTimeFirst",
      width: 150,
    },
    {
      title: "完成时间",
      dataIndex: "overTime",
      key: "overTime",
      width: 150,
    },
    {
      title: "备注",
      dataIndex: "notes",
      key: "notes",
      width: 400,
      align: "center",
      render: (_, item: any) =>
        item.notes.map((n: any) => {
          return (
            <Row>
              <Col>
                <a>{`${n.time}：${n.info}`}</a>
              </Col>
            </Row>
          );
        }),
    },
    {
      title: "描述",
      dataIndex: "describe",
      key: "describe",
      width: 400,
    },
  ];

  return (
    <div ref={ref}>
      <Row align="middle">
        <Col>{`项目: ${pData.name}`}</Col>
        <Col offset={2}>
          <Button
            type="primary"
            size="small"
            onClick={(e: any) => {
              e.stopPropagation();
              setExportVisible(true);
            }}
          >
            数据导出
          </Button>
        </Col>
      </Row>
      <br />
      <Row>
        <Col>
          <Form
            form={form}
            onFinish={onSearch}
            layout="inline"
            style={{ border: "1px solid rgb(59 130 246)", padding: "5px" }}
          >
            <Form.Item name="userid" label="负责人">
              <Select
                style={{ width: 100 }}
                onChange={() => {
                  setPagination((old) => {
                    old.current = 1;
                    old.pageSize = 8;
                    form.submit();
                  });
                }}
                options={allUsers}
              />
            </Form.Item>
            <Form.Item name="state" label="状态">
              <Select
                style={{ width: 100 }}
                onChange={() => {
                  setPagination((old) => {
                    old.current = 1;
                    old.pageSize = 8;
                    form.submit();
                  });
                }}
                options={[
                  { value: "0", label: "暂停" },
                  { value: "1", label: "执行中" },
                  { value: "2", label: "已完成" },
                ]}
              />
            </Form.Item>
            <Form.Item name="time" label="开始时间">
              <DatePicker.RangePicker
                format="YYYY-MM-DD"
                onChange={() => {
                  setPagination((old) => {
                    old.current = 1;
                    old.pageSize = 8;
                    form.submit();
                  });
                }}
              />
            </Form.Item>
            <Form.Item>
              <Button
                onClick={() => {
                  form.resetFields();
                  setPagination((old) => {
                    old.current = 1;
                    old.pageSize = 8;
                    form.submit();
                  });
                }}
              >
                {t("Restoration") /**复原 */}
              </Button>
            </Form.Item>
          </Form>
        </Col>
      </Row>
      <br />

      <Table
        rowKey={"id"}
        pagination={pagination}
        onChange={tabChangeHandle}
        columns={columns()}
        scroll={{ x: "100%", y: 800 }}
        dataSource={list}
      />

      <ExportDocDialog
        visible={exportVisible}
        title={pData.name}
        id={pData.id}
        onCancel={() => {
          setExportVisible(false);
        }}
        ulist={ulist}
      />
    </div>
  );
};

export default ProjectPlan;

const getPlanState = (state: string) => {
  let name = "";
  switch (state) {
    case "0":
      name = "暂停";
      break;
    case "1":
      name = "执行中";
      break;
    case "2":
      name = "已完成";
      break;
  }
  return name;
};

interface ExportDocProps {
  visible: boolean;
  title: string;
  id: string;
  onCancel: (flag?: boolean) => void;
  ulist: any;
}

const ExportDocDialog: React.FC<ExportDocProps> = (props) => {
  const { visible, title, id, onCancel, ulist } = props;
  const [form] = Form.useForm();
  const [saveLoading, setSaveLoading] = useState(false);

  const { runAsync: dataExport } = useRequest(projectService.dataExport, {
    manual: true,
  });

  const save = async (values: any) => {
    setSaveLoading(true);
    const startTime = dayjs(values.startTime).format("YYYY-MM-DD");
    const endTime = dayjs(values.endTime).format("YYYY-MM-DD");
    const [error, data] = await dataExport({
      id: id,
      startTime: startTime,
      endTime: endTime,
    });
    if (error) {
      antdUtils.message?.error(error);
      return;
    } else if (!data) {
      antdUtils.message?.error("接口出错");
      return;
    }
    const documentCreator = new DocumentCreator();
    const time = dayjs().format("YYYY-MM-DD");
    const doc = documentCreator.create({
      time: time,
      fName: title,
      fdata: data ? data : [],
      ulist: ulist,
    });
    Packer.toBlob(doc).then((blob) => {
      saveAs(blob, `${title}周汇报-${time}.docx`);
    });
    setSaveLoading(false);
    onCancel();
  };

  return (
    <Modal
      open={visible}
      title={`数据导出，项目：${title}`}
      onOk={() => {
        form.submit();
      }}
      confirmLoading={saveLoading}
      width={640}
      onCancel={() => {
        onCancel();
      }}
      afterClose={() => {
        form.resetFields();
        setSaveLoading(false);
      }}
      destroyOnClose
    >
      <Form
        form={form}
        onFinish={save}
        labelCol={{ flex: "0 0 100px" }}
        wrapperCol={{ span: 16 }}
      >
        <Form.Item
          label="开始时间"
          name="startTime"
          rules={[
            {
              required: true,
              message: "开始时间",
            },
          ]}
        >
          <DatePicker format="YYYY-MM-DD" />
        </Form.Item>
        <Form.Item
          label="结束时间"
          name="endTime"
          rules={[
            {
              required: true,
              message: "结束时间",
            },
          ]}
        >
          <DatePicker format="YYYY-MM-DD" />
        </Form.Item>
      </Form>
    </Modal>
  );
};
